# -*- coding: utf-8 -*-
"""
学习统计模型
目的：存储用户打卡统计数据，提供快速查询能力
职责：缓存统计结果，避免实时计算带来的性能问题
"""
from sqlalchemy import Column, Integer, DateTime, Date
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import func

Base = declarative_base()

class StudyStatistics(Base):
    """
    学习统计数据模型
    目的：预先计算并存储统计数据，提高查询性能，避免每次请求都实时计算
    功能：存储每日、每科目的打卡统计，包括打卡次数、总时长、连续天数等
    设计：使用唯一约束(user_id, subject_id, stat_date)防止重复统计
          subject_id为NULL时表示全部科目的汇总统计
    """
    __tablename__ = 'study_statistics'

    # 统计记录唯一标识符，主键，自增
    id = Column(Integer, primary_key=True, autoincrement=True, comment='统计记录唯一标识符')

    # 用户ID，外键关联users表，标识统计数据属于哪个用户
    user_id = Column(Integer, nullable=False, comment='用户ID')

    # 科目ID，外键关联study_subjects表
    # NULL表示全部科目的汇总统计，非NULL表示特定科目的统计
    subject_id = Column(Integer, nullable=True, comment='科目ID，NULL表示全部科目汇总')

    # 统计日期，记录统计数据对应的日期
    stat_date = Column(Date, nullable=False, comment='统计日期')

    # 打卡次数，当天该科目打卡的次数（按设计同一天同一科目只能打卡一次，所以通常为0或1）
    check_in_count = Column(Integer, nullable=False, default=0, comment='打卡次数')

    # 总学习时长（分钟），当天该科目的学习时长累计
    total_duration = Column(Integer, nullable=False, default=0, comment='总学习时长（分钟）')

    # 连续打卡天数，截止到stat_date的连续打卡天数
    # 连续的定义：从最近一次断签之后开始连续打卡的天数
    continuous_days = Column(Integer, nullable=False, default=0, comment='连续打卡天数')

    # 最大连续打卡天数，历史记录中的最长连续打卡天数
    # 用于展示用户的最佳学习记录
    max_continuous_days = Column(Integer, nullable=False, default=0, comment='最大连续打卡天数')

    # 创建时间，记录统计数据生成的时间
    created_at = Column(DateTime, nullable=False, default=func.now(), comment='创建时间')

    # 更新时间，记录统计数据最后更新的时间
    updated_at = Column(DateTime, nullable=False, default=func.now(),
                       onupdate=func.now(), comment='更新时间')

    def to_dict(self):
        """
        将统计记录对象转换为字典格式
        目的：方便API响应序列化，将数据库模型转换为JSON可序列化的格式
        功能：返回包含统计数据所有字段的字典

        Returns:
            dict: 包含统计数据的字典对象
        """
        return {
            'id': self.id,
            'user_id': self.user_id,
            'subject_id': self.subject_id,  # NULL表示全部科目汇总
            'stat_date': self.stat_date.isoformat() if self.stat_date else None,
            'check_in_count': self.check_in_count,
            'total_duration': self.total_duration,
            'continuous_days': self.continuous_days,
            'max_continuous_days': self.max_continuous_days,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None
        }
